package kv

import (
	"io"
	"log"
	"net/http"
	"strconv"
)

// 提供 http api 接口
type serverApi struct {
	store *kvStore
}

func NewServerApi(store *kvStore) *serverApi {
	return &serverApi{
		store: store,
	}
}

// 实现 http.Handler 接口
func (s *serverApi) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	key := req.RequestURI
	defer req.Body.Close()

	switch {
	case req.Method == "PUT":
		// set key value
		v, err := io.ReadAll(req.Body)
		if err != nil {
			log.Printf("Failed to read on PUT (%v)\n", err)
			http.Error(w, "Failed on PUT", http.StatusBadRequest)
			return
		}

		s.store.Propose(key, string(v))

		w.WriteHeader(http.StatusNoContent)
	case req.Method == "GET":
		if v, ok := s.store.Lookup(key); ok {
			w.Write([]byte(v))
		} else {
			http.Error(w, "Failed to GET", http.StatusNotFound)
		}
	}
}

func (s *serverApi) Start(port int, errorC <-chan error) {
	srv := http.Server{
		Addr:    ":" + strconv.Itoa(port),
		Handler: s,
	}

	go func() {
		if err := srv.ListenAndServe(); err != nil {
			log.Fatal(err)
		}
	}()

	if err, ok := <-errorC; ok {
		log.Fatal(err)
	}
}
